import cv2
import numpy as np
import math
class Color_detect(object):
    def __init__(self, cfg):
        self.cfg = cfg
        self.maxIndex = 0
        self.x = 0
        self.y = 0

    def Color_Pretreat(self, image, color):
        img_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

        lower_color = np.array(self.cfg[color][0])
        upper_color = np.array(self.cfg[color][1])

        mask = cv2.inRange(img_hsv, lowerb=lower_color, upperb=upper_color)
        k = np.ones((5, 5), np.uint8)
        mask = cv2.erode(mask, k)
        mask = cv2.medianBlur(mask, 9)
        cv2.imshow('mask', mask)
        cnts, he = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
        return cnts

    def Cnt_Pretreat(self, cnt):
        area = cv2.contourArea(cnt)
        (x, y, w, h) = cv2.boundingRect(cnt)
        if w > h:
            scale_w_h = w / h
        else:
            scale_w_h = h / w
        boundarea = w * h
        return scale_w_h, area, boundarea,

    def R_detect(self, image, cnts,i):
        self.maxIndex = i
        (self.x, self.y, w, h) = cv2.boundingRect(cnts[self.maxIndex])
        retval = cv2.minAreaRect(cnts[self.maxIndex])
        ret = list(retval)
        (RECTx, RECTy) = ret[1]
        print(ret[1])
        points = cv2.boxPoints(retval)
        points = np.int0(points)
        area1 = cv2.contourArea((cnts[self.maxIndex]))
        len_cnt = cv2.arcLength(cnts[self.maxIndex], True)
        (cx, cy), radius = cv2.minEnclosingCircle(cnts[self.maxIndex])
        center = (int(cx), int(cy))
        area_circle = radius * radius * 3.14
        if RECTx > RECTy:
            RectX_Y = RECTx / RECTy
        else:
            RectX_Y = RECTy / RECTx
        # 近似圆形时: 最小拟合矩形长宽比RectX_Y在（1，1.1）之间，轮廓面积比在（1，1.3）之间
        if 1 < RectX_Y < 1.2 and 1.35 > RECTx * RECTy / area1 > 1.1:
            if area_circle/area1 < 0.95 or area_circle/area1 > 1.33:
                print('no')
            else:
                cv2.drawContours(image, [points], 0, (0, 255, 255), 1)
                cv2.drawContours(image, [cnts[self.maxIndex]], 0, (255, 255, 0), 1)
                cv2.putText(image, 'red', (self.x, self.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)

        # 近似矩形时: 最小拟合矩形长宽比RectX_Y在（1.2，1.55）之间，轮廓面积比在（1，1.3）之间
        if 1.2 < RectX_Y < 1.55 and 1.3 > RECTx * RECTy / area1 > 1:
            # 最小矩形周长小于轮廓周长（过滤内部较大不规则形状）
            if 2 * (RECTx + RECTy) < len_cnt or RECTx * RECTy / area1 > 1.2:
                print('no_L', 2 * (RECTx + RECTy) / len_cnt)
            else:
                cv2.drawContours(image, [points], 0, (0, 255, 255), 1)
                cv2.drawContours(image, [cnts[self.maxIndex]], 0, (255, 255, 0), 1)
                cv2.putText(image, 'red', (self.x, self.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)

    def B_detect(self, image, cnts, i):
        self.maxIndex = i
        (self.x, self.y, w, h) = cv2.boundingRect(cnts[self.maxIndex])
        retval = cv2.minAreaRect(cnts[self.maxIndex])
        ret = list(retval)
        (RECTx, RECTy) = ret[1]
        points = cv2.boxPoints(retval)
        points = np.int0(points)
        area1 = cv2.contourArea((cnts[self.maxIndex]))
        len_cnt = cv2.arcLength(cnts[self.maxIndex], True)
        if RECTx > RECTy:
            RectX_Y = RECTx / RECTy
        else:
            RectX_Y = RECTy / RECTx
        # 近似圆形时: 最小拟合矩形长宽比RectX_Y在（1，1.1）之间，轮廓面积比在（1，1.3）之间
        if 1 < RectX_Y < 1.2 and 1.3 > RECTx * RECTy / area1 > 1:
            if len_cnt > 1.1 * 3.14 * RECTx:
                print('no')
            else:
                cv2.drawContours(image, [points], 0, (0, 255, 255), 1)
                cv2.drawContours(image, [cnts[self.maxIndex]], 0, (255, 255, 0), 1)
                cv2.putText(image, 'blue', (self.x, self.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)

# 近似矩形时: 最小拟合矩形长宽比RectX_Y在（1.2，1.67）之间，轮廓面积比在（1，1.3）之间
        if 1.2 < RectX_Y < 1.67 and 1.3 > RECTx * RECTy / area1 > 1:
            # 最小矩形周长小于轮廓周长（过滤内部较大不规则形状）
            if (2 * (RECTx + RECTy) / len_cnt) < 0.98 or 1.08 > RECTx * RECTy / area1 > 1:
                print('no_L', 2 * (RECTx + RECTy) / len_cnt)
            else:
                cv2.drawContours(image, [points], 0, (0, 255, 255), 1)
                cv2.drawContours(image, [cnts[self.maxIndex]], 0, (255, 255, 0), 1)
                cv2.putText(image, 'blue', (self.x, self.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)

    def Yellow_detect(self, image, cnts, i):
        self.maxIndex = i
        (self.x, self.y, w, h) = cv2.boundingRect(cnts[self.maxIndex])
        retval = cv2.minAreaRect(cnts[self.maxIndex])
        ret = list(retval)
        (RECTx, RECTy) = ret[1]
        points = cv2.boxPoints(retval)
        points = np.int0(points)
        area1 = cv2.contourArea((cnts[self.maxIndex]))
        if RECTx > RECTy:
            RectX_Y = RECTx / RECTy
        else:
            RectX_Y = RECTy / RECTx
        (cx, cy), radius = cv2.minEnclosingCircle(cnts[self.maxIndex])
        center = (int(cx), int(cy))
        area_circle = radius * radius * 3.14
        M = cv2.moments(cnts[self.maxIndex])
        cX = int(M['m10'] / M['m00'])
        cY = int(M['m01'] / M['m00'])

        cv2.circle(image, center, 7, (255, 255, 255), -1)
        cv2.circle(image, (cX, cY), 7, (255, 0, 255), -1)
        cv2.circle(image, center, int(radius), (255, 255, 255), 2)

        dis_circle = math.sqrt(abs((abs(cX - cx) ** 2) - (abs(cY - cy) ** 2)))
        # 近似矩形时:最小拟合矩形长宽比RectX_Y在（1.1，1.55）之间   轮廓面积比在（1，1.3）之间（总体限制）
        if 1 < RectX_Y < 1.55:
            if RECTx * RECTy / area1 < 1.35 and dis_circle < 2.7 and area_circle / area1 > 1.2 and area_circle / area1 < 1.55:
                cv2.drawContours(image, [points], 0, (0, 255, 255), 1)
                cv2.drawContours(image, [cnts[self.maxIndex]], 0, (255, 255, 0), 1)
                cv2.putText(image, 'yellow rect', (self.x, self.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 3)

